home *** CD-ROM | disk | FTP | other *** search
- /* $VER: $Id: area.c,v 1.9 1994/01/12 07:47:46 tf Exp $ © 1992,93 by Tobias Ferber */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <graphics/gfx.h>
- #include <graphics/gfxmacros.h>
- #include <intuition/intuition.h>
- #include <time.h>
- #include "timer.h"
-
- /* globals = */
- static struct GfxBase *GfxBase;
- static struct IntuitionBase *IntuitionBase;
- static struct Window *win;
- static struct AreaInfo areainfo;
- static struct TmpRas tras;
- static APTR areabuf= (APTR)NULL;
- static PLANEPTR trasbuf= (PLANEPTR)NULL;
- static BOOL menuflag= FALSE;
-
- /* the following vd_xxxx are all set by rethink_dimensions() */
- static short vd_width, /* current vector digit dimensions */
- vd_height,
- vd_ypos,
- vd_spcx;
-
- #define MAXVECTORS (64*6) /* for the area stuff */
- #define AREASIZE ((MAXVECTORS+1) * 5) /* +1 vector for AreaEnd() */
- #define TRASSIZE ((win->WScreen->Width/8) * win->WScreen->Height)
-
- static struct NewWindow nw= {
- 0,0,
- 350,55,
- -1,-1,
- CLOSEWINDOW|MENUPICK|NEWSIZE,
- GIMMEZEROZERO|SMART_REFRESH,
- NULL,NULL,
- (UBYTE*)"vClock",
- NULL,NULL,
- 130,20,
- -1,-1,
- WBENCHSCREEN
- };
-
- struct IntuiText quit_text= {
- 0,1,JAM1,1,1,NULL,"Quit", NULL,
- };
-
- struct MenuItem quit_item= {
- NULL, 0,0, 0,0, ITEMENABLED|HIGHCOMP|ITEMTEXT|COMMSEQ, 0,
- (APTR)&quit_text, NULL, 'Q', NULL, 0
- };
-
- struct Menu menu= {
- NULL, 0,0, 0,0, MENUENABLED, (BYTE *)"Project", &quit_item, 0,0,0,0
- };
-
- #define EDGES 8
-
- struct ptxy { short x,y; } a,b,c,d,e,f,g, /* segment offset */
- top[EDGES],
- bottom[EDGES],
- left[EDGES],
- right[EDGES],
- mid[4];
-
- /* Init the vector tables of all segments of a vector digit with
- * width w and height h. This function will be called when using
- * rethink_dimensions().
- */
-
- void init_vectors(short w, short h)
- {
- unsigned short dx1= (5*w+4)/8,
- dx2= (w+1)/2,
- dx3= (w+4)/8,
- dx4= (w+8)/16,
- dy1= (3*h+4)/8,
- dy2= (h+2)/4,
- dy3= (h+4)/8,
- dy4= (h+8)/16;
-
- /* corrections */
-
- dx1= dx4+dx2+dx4;
- dy1= dy4+dy2+dy4;
-
- /*
- printf("dx1=%d, dx2=%d, dx3=%d, dx4=%d, "
- "dy1=%d, dy2=%d, dy3=%d, dy4=%d\n",dx1,dx2,dx3,dx4,
- dy1,dy2,dy3,dy4 );
- */
-
- /* segment offsets */
-
- a.x= dx3+dx4; a.y= 0;
- b.x= dx3+2*dx4+dx1; b.y= dy4;
- c.x= dx3+2*dx4+dx1; c.y= 2*dy4+dy1;
- d.x= dx3+2*dx4; d.y= 2*dy1+2*dy4;
- e.x= 0; e.y= 2*dy4+dy1;
- f.x= 0; f.y= dy4;
- g.x= dx3+2*dx4; g.y= dy4+dy1;
-
- /* delta values */
-
- top[0].x= dx1; top[0].y= 0;
- top[1].x= 0; top[1].y= dy4;
- top[2].x= -dx4; top[2].y= 0;
- top[3].x= 0; top[3].y= dy4;
- top[4].x= -dx2; top[4].y= 0;
- top[5].x= 0; top[5].y= -dy4;
- top[6].x= -dx4; top[6].y= 0;
- top[7].x= 0; top[7].y= -dy4;
-
- right[0].x= dx3; right[0].y= 0;
- right[1].x= 0; right[1].y= dy1;
- right[2].x= -dx3; right[2].y= 0;
- right[3].x= 0; right[3].y= -dy4;
- right[4].x= -dx4; right[4].y= 0;
- right[5].x= 0; right[5].y= -dy2;
- right[6].x= dx4; right[6].y= 0;
- right[7].x= 0; right[7].y= -dy4;
-
- left[0].x= dx3; left[0].y= 0;
- left[1].x= 0; left[1].y= dy4;
- left[2].x= dx4; left[2].y= 0;
- left[3].x= 0; left[3].y= dy2;
- left[4].x= -dx4; left[4].y= 0;
- left[5].x= 0; left[5].y= dy4;
- left[6].x= -dx3; left[6].y= 0;
- left[7].x= 0; left[7].y= -dy1;
-
- bottom[0].x= dx2; bottom[0].y= 0;
- bottom[1].x= 0; bottom[1].y= dy4;
- bottom[2].x= dx4; bottom[2].y= 0;
- bottom[3].x= 0; bottom[3].y= dy4;
- bottom[4].x= -dx1; bottom[4].y= 0;
- bottom[5].x= 0; bottom[5].y= -dy4;
- bottom[6].x= dx4; bottom[6].y= 0;
- bottom[7].x= 0; bottom[7].y= -dy4;
-
- mid[0].x= dx2; mid[0].y= 0;
- mid[1].x= 0; mid[1].y= dy3;
- mid[2].x= -dx2; mid[2].y= 0;
- mid[3].x= 0; mid[3].y= -dy3;
- }
-
- /* rethink the vector digit dimensions for the hh:mm:ss display
- * in a rastport of width w and height h and call init_vectors()
- */
-
- void rethink_dimensions(void)
- {
- short ww= win->Width - win->BorderLeft - win->BorderRight,
- wh= win->Height - win->BorderTop - win->BorderBottom;
-
- vd_ypos = (wh + 7) / 13;
- vd_spcx = (ww + 16) / 32;
- vd_height = wh - (2 * vd_ypos) - 4;
- vd_width = (ww - 9 * vd_spcx) / 6;
-
- init_vectors(vd_width, vd_height);
- /*
- printf("vd_ypos=%d, vd_spcx=%d, vd_height=%d, vd_width=%d\n",
- vd_ypos,vd_spcx,vd_height,vd_width);
- */
- }
-
- /* Missing in the graphics.library ? */
-
- void AreaPolyDraw(struct RastPort *rp, short x,
- short y,
- short edges,
- short dxy[])
- { short e;
- AreaMove(rp,x,y);
- for(e=0;e<edges;e++)
- { x+= dxy[2*e];
- y+= dxy[2*e+1];
- AreaDraw(rp,x,y);
- }
- }
-
- /* Render a vector digit at (xpos|ypos) into the given RastPort rp.
- * Note that this RastPort *MUST* have a fully initialized TmpRas
- * and AreaInfo structure.
- * If you pass a 'smart' value >=0 to this function, it only
- * changes the differing segments between `digit' and `smart'.
- * SET segments will be filled with rp's FgPen, UNSET segments
- * using the BgPen.
- * Passed digit and smart values *MUST* be in [0..15], except
- * smart which can be -1 for non-smart rendering.
- */
-
- void render_vecdigit(struct RastPort *rp,short xpos,
- short ypos,
- int digit,
- int smart)
- { static const UBYTE seglist[17][8]= {
- /* a b c d e f g */
- { 1,1,1,1,1,1,0 }, /* 0 */
- { 0,1,1,0,0,0,0 }, /* 1 aaaaaaaaaa */
- { 1,1,0,1,1,0,1 }, /* 2 ff aaaaaaaa bb */
- { 1,1,1,1,0,0,1 }, /* 3 fff bbb */
- { 0,1,1,0,0,1,1 }, /* 4 fff bbb */
- { 1,0,1,1,0,1,1 }, /* 5 fff bbb */
- { 1,0,1,1,1,1,1 }, /* 6 ff bb */
- { 1,1,1,0,0,0,0 }, /* 7 gggggggg */
- { 1,1,1,1,1,1,1 }, /* 8 ee gggggggg cc */
- { 1,1,1,1,0,1,1 }, /* 9 eee ccc */
- { 1,1,1,0,1,1,1 }, /* A eee ccc */
- { 0,0,1,1,1,1,1 }, /* B eee ccc */
- { 1,0,0,1,1,1,0 }, /* C ee dddddddd cc */
- { 0,1,1,1,1,0,1 }, /* D dddddddddd */
- { 1,0,0,1,1,1,1 }, /* E */
- { 1,0,0,0,1,1,1 } }; /* F */
-
- if(smart<0)
- { if(seglist[digit][0]) AreaPolyDraw(rp,xpos+a.x,ypos+a.y,EDGES,top);
- if(seglist[digit][1]) AreaPolyDraw(rp,xpos+b.x,ypos+b.y,EDGES,right);
- if(seglist[digit][2]) AreaPolyDraw(rp,xpos+c.x,ypos+c.y,EDGES,right);
- if(seglist[digit][3]) AreaPolyDraw(rp,xpos+d.x,ypos+d.y,EDGES,bottom);
- if(seglist[digit][4]) AreaPolyDraw(rp,xpos+e.x,ypos+e.y,EDGES,left);
- if(seglist[digit][5]) AreaPolyDraw(rp,xpos+f.x,ypos+f.y,EDGES,left);
- if(seglist[digit][6]) AreaPolyDraw(rp,xpos+g.x,ypos+g.y,4,mid);
- AreaEnd(rp);
- }
- else
- { BYTE apen= rp->FgPen;
- if(seglist[digit][0] &! seglist[smart][0])
- AreaPolyDraw(rp,xpos+a.x,ypos+a.y,EDGES,top);
- if(seglist[digit][1] &! seglist[smart][1])
- AreaPolyDraw(rp,xpos+b.x,ypos+b.y,EDGES,right);
- if(seglist[digit][2] &! seglist[smart][2])
- AreaPolyDraw(rp,xpos+c.x,ypos+c.y,EDGES,right);
- if(seglist[digit][3] &! seglist[smart][3])
- AreaPolyDraw(rp,xpos+d.x,ypos+d.y,EDGES,bottom);
- if(seglist[digit][4] &! seglist[smart][4])
- AreaPolyDraw(rp,xpos+e.x,ypos+e.y,EDGES,left);
- if(seglist[digit][5] &! seglist[smart][5])
- AreaPolyDraw(rp,xpos+f.x,ypos+f.y,EDGES,left);
- if(seglist[digit][6] &! seglist[smart][6])
- AreaPolyDraw(rp,xpos+g.x,ypos+g.y,4,mid);
- AreaEnd(rp);
-
- SetAPen(rp,rp->BgPen);
- if(seglist[smart][0] &! seglist[digit][0])
- AreaPolyDraw(rp,xpos+a.x,ypos+a.y,EDGES,top);
- if(seglist[smart][1] &! seglist[digit][1])
- AreaPolyDraw(rp,xpos+b.x,ypos+b.y,EDGES,right);
- if(seglist[smart][2] &! seglist[digit][2])
- AreaPolyDraw(rp,xpos+c.x,ypos+c.y,EDGES,right);
- if(seglist[smart][3] &! seglist[digit][3])
- AreaPolyDraw(rp,xpos+d.x,ypos+d.y,EDGES,bottom);
- if(seglist[smart][4] &! seglist[digit][4])
- AreaPolyDraw(rp,xpos+e.x,ypos+e.y,EDGES,left);
- if(seglist[smart][5] &! seglist[digit][5])
- AreaPolyDraw(rp,xpos+f.x,ypos+f.y,EDGES,left);
- if(seglist[smart][6] &! seglist[digit][6])
- AreaPolyDraw(rp,xpos+g.x,ypos+g.y,4,mid);
- AreaEnd(rp);
- SetAPen(rp,apen);
- }
- }
-
- void set_vclock(struct RastPort *rp, int h, int m, int s, int clr)
- {
- static int _hh= -1, _h= -1,
- _mm= -1, _m= -1,
- _ss= -1, _s= -1;
-
- int hh= h/10,
- mm= m/10,
- ss= s/10;
-
- h%=10;
- m%=10;
- s%=10;
-
- if(clr) _hh= _h= _mm= _m= _ss= _s= -1;
-
- if(_hh!=hh)
- { render_vecdigit(rp,vd_spcx,vd_ypos,hh,_hh);
- _hh=hh;
- }
- if(_h!=h)
- { render_vecdigit(rp,vd_width+2*vd_spcx,vd_ypos,h,_h);
- _h=h;
- }
- if(_mm!=mm)
- { render_vecdigit(rp,2*vd_width+4*vd_spcx,vd_ypos,mm,_mm);
- _mm=mm;
- }
- if(_m!=m)
- { render_vecdigit(rp,3*vd_width+5*vd_spcx,vd_ypos,m,_m);
- _m=m;
- }
- if(_ss!=ss)
- { render_vecdigit(rp,4*vd_width+7*vd_spcx,vd_ypos,ss,_ss);
- _ss=ss;
- }
- if(_s!=s)
- { render_vecdigit(rp,5*vd_width+8*vd_spcx,vd_ypos,s,_s);
- _s=s;
- }
- }
-
- /* open the system stuff and allocate needed memory */
-
- int open_vectorstuff(void)
- { int ok=0;
- if(IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",0L))
- { struct Screen s; /* for the Workbench Screen data */
- if(GetScreenData(&s,sizeof(struct Screen),WBENCHSCREEN,NULL))
- { short hc= s.WBorLeft + s.WBorRight,
- vc= s.WBorTop + s.WBorBottom;
-
- if(nw.Title) vc += s.Font->ta_YSize + 1;
-
- nw.Width += hc; nw.MinWidth += hc;
- nw.Height += vc; nw.MinHeight += vc;
-
- if(nw.Width < nw.MinWidth) nw.Width = nw.MinWidth;
- if(nw.Height < nw.MinHeight) nw.Height = nw.MinHeight;
-
- if(nw.LeftEdge+nw.Width > s.Width)
- { if(nw.Width > s.Width) nw.Width= s.Width;
- nw.LeftEdge= s.Width-nw.Width;
- }
- if(nw.TopEdge+nw.Height > s.Height)
- { if(nw.Height > s.Height) nw.Height= s.Height;
- nw.TopEdge= s.Height-nw.Height;
- }
- }
- if(GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",0L))
- { if(win=(struct Window *)OpenWindow(&nw))
- { if(areabuf= (APTR)AllocMem(AREASIZE,MEMF_PUBLIC|MEMF_CLEAR))
- { if(trasbuf= (PLANEPTR)AllocRaster(win->WScreen->Width,
- win->WScreen->Height))
- { InitArea(&areainfo,areabuf,MAXVECTORS);
- win->RPort->AreaInfo=&areainfo;
- win->RPort->TmpRas=(struct TmpRas *)
- InitTmpRas(&tras,trasbuf,TRASSIZE);
- quit_text.ITextFont= win->WScreen->Font;
- quit_item.Height= 2 + win->WScreen->Font->ta_YSize;
- quit_item.Width= 4 * IntuiTextLength(&quit_text);
- menu.Width= quit_item.Width;
- menuflag= SetMenuStrip(win,&menu);
- ok= menuflag ? 1:0;
- }
- else free(areabuf);
- }
- else CloseWindow(win);
- }
- else CloseLibrary(GfxBase);
- }
- else CloseLibrary(IntuitionBase);
- }
- return ok;
- }
-
- void close_vectorstuff(void)
- { if(menuflag && win) ClearMenuStrip(win);
- if(trasbuf) FreeRaster(trasbuf,win->WScreen->Width,
- win->WScreen->Height);
- if(areabuf) FreeMem(areabuf,AREASIZE);
- if(win) CloseWindow(win);
- if(GfxBase) CloseLibrary(GfxBase);
- if(IntuitionBase) CloseLibrary(IntuitionBase);
- }
-
- update_titles(struct Window *w, struct tm *lt)
- { static const char *dn[]= { "Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sun" },
- *mn[]= { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug",
- "Sep","Oct","Nov","Dec" };
-
- static int d= -1, m= -1, y= -1;
- static char wtitle[20];
-
- if(d != lt->tm_mday || m != lt->tm_mon || y != lt->tm_year)
- { d= lt->tm_mday;
- m= lt->tm_mon;
- y= lt->tm_year;
- sprintf(wtitle,"%s %02d-%s-%02d",dn[lt->tm_wday],d,mn[m],y);
- SetWindowTitles(w,wtitle,-1L); /* -1 = old title */
- }
- }
-
- int do_vclock(short leftedge,
- short topedge,
- short width,
- short height,
- short setpen,
- short unsetpen,
- short outline,
- short backfill,
- short notitle,
- long wflags)
-
- { int rc= -1; /* return code; != 0 indicates failure */
-
- nw.LeftEdge= leftedge;
- nw.TopEdge= topedge;
- nw.Width= width;
- nw.Height= height;
- nw.Flags |= wflags;
- if(notitle) nw.Title= (UBYTE *)NULL;
-
- if( open_vectorstuff() )
- { struct timerequest *tr= open_timer(NULL,0L);
- if(tr != (struct timerequest *)NULL)
- { struct MsgPort *tp= tr->tr_node.io_Message.mn_ReplyPort;
- struct RastPort *rp= win->RPort;
- BOOL done= FALSE;
-
- rc= 0;
- queue_timer(tr,1,0);
- rethink_dimensions();
- SetAPen(rp,setpen);
- SetBPen(rp,unsetpen);
- SetOPen(rp,outline);
- SetRast(rp,backfill);
- /*BNDRYOFF(rp);*/
- set_vclock(rp,88,88,88,-1); /* all segments high to init bndry */
-
- while(!done)
- {
- long timersigmask = (1L << tp->mp_SigBit),
- usersigmask = (1L << win->UserPort->mp_SigBit),
- breaksigmask = SIGBREAKF_CTRL_C,
-
- sig = Wait(timersigmask | usersigmask | breaksigmask);
-
- done |= (sig & breaksigmask);
-
- if(sig & timersigmask)
- {
- while(GetMsg(tp) != (struct Message *)NULL)
- ;
-
- if(CheckIO((struct IORequest *)tr))
- {
- long t;
- struct tm *lt;
- time(&t);
- lt= (struct tm *)localtime(&t);
- set_vclock(rp,lt->tm_hour,lt->tm_min,lt->tm_sec,0);
-
- if(!notitle)
- update_titles(win,lt);
-
- queue_timer(tr,1,0);
- }
- }
- if(sig & usersigmask)
- {
- ULONG class;
- UWORD code;
- struct IntuiMessage *imsg;
- while(imsg= (struct IntuiMessage *)GetMsg(win->UserPort))
- { code= imsg->Code;
- done |= ((class= imsg->Class) == CLOSEWINDOW);
- ReplyMsg((struct Message *)imsg);
-
- switch(class)
- {
- case NEWSIZE:
- rethink_dimensions();
- SetRast(rp,backfill);
- set_vclock(rp,88,88,88,-1);
- break;
-
- case MENUPICK:
- while(code != MENUNULL)
- { struct MenuItem *mi= (struct MenuItem *)ItemAddress(&menu,code);
- done |= (MENUNUM(code) == 0 && ITEMNUM(code) == 0);
- code= (mi && mi->NextSelect != code) ? mi->NextSelect : MENUNULL;
- }
- break;
- }
- }
- }
- }
- purge_timer(tr);
- close_timer(tr);
- }
- close_vectorstuff();
- }
- return rc;
- }
-